package com.example.myapplication.NettyClient;


import android.util.Log;

import com.example.myapplication.Base.BaseActivity;
import com.example.myapplication.Entity.HeartMessage;
import com.example.myapplication.Entity.InitMessage;
import com.example.myapplication.Entity.Packet;

import java.util.concurrent.TimeUnit;

import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.EventLoop;
import io.netty.handler.timeout.IdleState;
import io.netty.handler.timeout.IdleStateEvent;


/**
 *
 */
public class ChatClientHandler extends ChannelInboundHandlerAdapter {
    private static final String TAG = "ChatClientHandler";
    /**
     * 在channel注册好后，激活channel，即将channel所对于的客户端与服务器进行连接
     * @param ctx ChannelHandlerContext类型
     * @throws Exception
     */
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        InitMessage msg = new InitMessage("", "server", "login!");
        Log.e(TAG, "channelActive: "+ msg.getClass());
        // 向服务器发送认证消息，通知服务器新加入了一个客户端
        ctx.channel().writeAndFlush(msg);
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        super.channelInactive(ctx);
        Log.e(TAG, "channelInactive: ");
        EventLoop loop = ctx.channel().eventLoop();
        loop.schedule(new Runnable() {
            @Override
            public void run() {
                Log.e(TAG, "连接断开，发起重连");
                BaseActivity.client.reConnect();
            }
        }, 5, TimeUnit.SECONDS);

    }

    /**
     * 当服务器发送消息过来时，即channel读取到数据时
     * @param ctx
     * @param msg 读取到的消息
     * @throws Exception
     */
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        Log.e(TAG, "channelRead: "+ctx.name());
        Log.e(TAG, "channelRead: "+msg.toString());
        Packet packet = (Packet) msg;
        packet.setCtx(ctx);
        packet.process();
    }

    /**
     * 捕获异常，关闭channel
     * @param ctx
     * @param cause 异常的类型
     * @throws Exception
     */
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        // 获得当前的channel
        Channel newchannel = ctx.channel();
        Log.e(TAG, "exceptionCaught: "+"["+newchannel.remoteAddress()+"]：通讯异常");
        Log.e(TAG, "exceptionCaught: "+cause.getMessage());
        newchannel.close();
    }

    /**
     * 心跳包发送
     * */
    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
        super.userEventTriggered(ctx, evt);
        Log.i(TAG, "userEventTriggered : ");
        if (evt instanceof IdleStateEvent) {
            if (((IdleStateEvent) evt).state() == IdleState.READER_IDLE) {
                Log.i(TAG, "userEventTriggered 心跳包发送: ");
                sendHeartPkg(ctx);
            }
        } else {
            super.userEventTriggered(ctx, evt);
        }

    }

    /**
     * 发送心跳
     */
    private void sendHeartPkg(ChannelHandlerContext ctx) {
        HeartMessage bean = new HeartMessage("","","心跳包");
        ctx.channel().writeAndFlush(bean);
        Log.d(TAG, "客户端发送心跳成功");
    }

}